Skip to content

Add support for ListView #92

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open

Add support for ListView #92

wants to merge 4 commits into from

Conversation

grod220
Copy link
Member

@grod220 grod220 commented Jun 6, 2025

Currently, PodSliceMut has served as the data structure for dynamically sized list. As we expand functionality to this, it is starting to feel misnamed (as Slices generally aren't things that are resized).

Changes made

  • Add new ListView struct that serves as the future home for mutations involving ordered lists
  • Copy over methods 1:1 from PodSliceMut: unpack, init, push
  • Add new methods: remove, len, iter, and new tests
  • Mark PodSliceMut as deprecated

@grod220 grod220 force-pushed the podslice-remove-methods branch 3 times, most recently from 4f972f1 to 817eb9f Compare June 6, 2025 12:33
@grod220 grod220 requested review from febo, joncinque and buffalojoec June 6, 2025 12:36
Copy link
Contributor

@joncinque joncinque left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mostly small points, looks good to me!

As another naming idea, what we're really providing is a View on existing data, so it's like a Vec that won't reallocate, which also similar to an arena allocator.

So we could go with ListView or NoAllocVec or ArenaList. I kind of like the last one, since it might describe the situation best.

Copy link
Contributor

@febo febo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks very nice – left a few comments. The main one is about the alignment. It would be nice if we could make it more flexible to support types 8-byte aligned.

@febo
Copy link
Contributor

febo commented Jun 7, 2025

So we could go with ListView or NoAllocVec or ArenaList. I kind of like the last one, since it might describe the situation best.

I have a slight preference for ListView – I am not sure if users will make the connection between arena allocator and ArenaList. 😊

@buffalojoec
Copy link
Contributor

So we could go with ListView or NoAllocVec or ArenaList. I kind of like the last one, since it might describe the situation best.

I have a slight preference for ListView – I am not sure if users will make the connection between arena allocator and ArenaList. 😊

Agreed, I personally have never heard the term "arena" in this context before, and I assume most developers will whiff on the underlying meaning at first. However, "view" implies readonly, and that's not the case here.

Here are a few ideas:

  • PodList (I think it's actually ok)
  • StackList
  • BoxList
  • Dynamic + any of the above
  • PodSpan

@febo
Copy link
Contributor

febo commented Jun 7, 2025

So we could go with ListView or NoAllocVec or ArenaList. I kind of like the last one, since it might describe the situation best.

I have a slight preference for ListView – I am not sure if users will make the connection between arena allocator and ArenaList. 😊

Agreed, I personally have never heard the term "arena" in this context before, and I assume most developers will whiff on the underlying meaning at first. However, "view" implies readonly, and that's not the case here.

Here are a few ideas:

  • PodList (I think it's actually ok)
  • StackList
  • BoxList
  • Dynamic + any of the above
  • PodSpan

Agree with your point on the "View" implying read-only, but while the type has a "dynamic" size its capacity is fixed. In that sense it is a view. 😊

The only concern that I have with using Pod* is that the type itself is not Pod, so it might look a bit odd.

Copy link
Member Author

@grod220 grod220 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the delay on this! Wasn't quite sure we were going to need this until recent confirmations in the Unstake program.

@grod220 grod220 force-pushed the podslice-remove-methods branch from 817eb9f to 56057f1 Compare July 9, 2025 11:53
@grod220 grod220 changed the title Add support for PodList Add support for ListView Jul 9, 2025
@grod220 grod220 requested review from buffalojoec, joncinque and febo July 9, 2025 12:21
Copy link
Contributor

@buffalojoec buffalojoec left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome!! This is looking fantastic, and the diagrams under unpack_internal are really an elegant touch for helping follow the slice processing.

Comment on lines +20 to +29
let remainder = length_size
.checked_rem(data_align)
.ok_or(ProgramError::ArithmeticOverflow)?;
if remainder == 0 {
Ok(0)
} else {
data_align
.checked_sub(remainder)
.ok_or(ProgramError::ArithmeticOverflow)
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This block could be simplified:

Suggested change
let remainder = length_size
.checked_rem(data_align)
.ok_or(ProgramError::ArithmeticOverflow)?;
if remainder == 0 {
Ok(0)
} else {
data_align
.checked_sub(remainder)
.ok_or(ProgramError::ArithmeticOverflow)
}
length_size
.checked_rem(data_align)
.and_then(|rem| data_align.checked_sub(rem))
.ok_or(ProgramError::ArithmeticOverflow)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately this triggers test failures. It fails when the data is already aligned because it doesn't handle the remainder == 0 case. For example, to align a 4-byte header for 2-byte data, the padding should be 0. This snippet calculates 2 - (4 % 2) which is 2 - 0 = 2.

Copy link
Member Author

@grod220 grod220 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few things I am realizing.

1 - With unstake program’s new settlement design, we no longer need the remove functions.
2 - Users of ListView will not be able to use PodSlice for read-only use (if they rely upon the default len bytes). Pod64 vs Pod32 defaults. Given ListView now has iterable methods, it sort of seems like it could replace both PodSlice & PodSliceMut.

Up for discussion if this is worth keeping or not. The benefits are better alignment handling, remove functions, and test coverage. But perhaps these features are not pressing any longer.

Comment on lines +20 to +29
let remainder = length_size
.checked_rem(data_align)
.ok_or(ProgramError::ArithmeticOverflow)?;
if remainder == 0 {
Ok(0)
} else {
data_align
.checked_sub(remainder)
.ok_or(ProgramError::ArithmeticOverflow)
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately this triggers test failures. It fails when the data is already aligned because it doesn't handle the remainder == 0 case. For example, to align a 4-byte header for 2-byte data, the padding should be 0. This snippet calculates 2 - (4 % 2) which is 2 - 0 = 2.

@grod220 grod220 requested a review from buffalojoec July 15, 2025 13:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants